﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using System.Text;
using EventbriteService;
using EventbriteService.Model;
using EventbriteService.Util;
using EventbriteService.Adapter;
using EventbriteService.Factory;

namespace Eventbrite.LinqProvider
{

    public class LinqReader : Client, IDataReader
    {
        public IEnumerable<T> Read<T>(RequestInfo request)
        {
            var requestUrl = base.CreateRequestForMethod(APIMethods.EventSearch)
                                .AddQueryString(request.UrlRequest )
                                .Expand()
                                //.AddRepeatSchedule()
                                .Build();

            var doc = base.GetResponse(requestUrl); 
            IDataAdapter data;
            try
            {
                data = base.CreateAdapter(doc);
            }
            catch (EventbriteException ex)
            {

                if (request.IsDefaultSet && ex.ErrorType == "Not Found")
                {
                    return null;
                }

                throw;
            }

            if (request.IsCount)
            {
                return GetCountValue<T>(data);
                
            }
            else if (request.LambdaExpression == null)
            {
                return new Mapper<T>(data).Build();
            }
            else
            {
                return Mapper<T>.BuildProjection(request.LambdaExpression, data);
            }

        }

        private IEnumerable<T> GetCountValue<T>(IDataAdapter data)
        {
            T result = default(T);
            var val = data.Root.Elements().SingleOrDefault(e => e.Name == "summary");
            val = val.Elements().First(e => e.Name == "total_items");
            result = GetValFromString<T>(val.Value);
            yield return result;

        }

        private static T GetValFromString<T>(string s)
        {
            if (string.IsNullOrEmpty(s))
                s = "0";
            return (T)Convert.ChangeType(s, typeof(T));
        }
    }
}
